<?php

class Silk_Mapi_Model_Api2_Checkout extends Mage_Api2_Model_Resource
{
    /**
     * @var Mage_Sales_Model_Quote
     */
    protected $_quote;

    /**
     * @var int
     */
    protected $_hasError = 0;

    /**
     * @var Mage_Customer_Model_Entity_Address
     */
    protected $address;

    /**
     * @return Mage_Checkout_Model_Cart
     */
    protected function _getCart()
    {
        return Mage::getSingleton('checkout/cart');
    }

    /**
     * @param bool $reload
     * @return Mage_Sales_Model_Quote
     * @throws Exception
     * @throws Mage_Api2_Exception
     */
    protected function _getQuote($reload = false)
    {
        if (!$this->_quote || $reload) {
            $customer = $this->_getCustomer();

            /** @var Mage_Sales_Model_Quote $quote */
            $quote = Mage::getModel('sales/quote')->setStoreId(Mage::app()->getStore()->getId());
            $quote->loadByCustomer($customer->getId());
            if ($quote->getId()) {
                $this->_quote = $quote;
            } else {
                $quote = Mage::getModel('sales/quote')->setStoreId(Mage::app()->getStore()->getId());
                $quote->assignCustomer($customer);
                $quote->save();
                $this->_quote = $quote;
            }
        }

        return $this->_quote;
    }
   
    /**
     * @param Mage_Sales_Model_Quote $quote
     */
    protected function setQuote(Mage_Sales_Model_Quote $quote)
    {
        if ($quote instanceof Mage_Sales_Model_Quote)
            $this->_quote = $quote;
    }

    /**
     * Get one page checkout model
     *
     * @return Mage_Checkout_Model_Type_Onepage
     */
    public function getOnepage()
    {
        return Mage::getSingleton('checkout/type_onepage');
    }

    /**
     * @return Mage_Checkout_Model_Session
     */
    public function _getCheckoutSession()
    {
        return Mage::getSingleton('checkout/session');
    }

    /**
     * @return Mage_Customer_Model_Session
     */
    public function _getCustomerSession()
    {
        return Mage::getSingleton('customer/session');
    }

    /**
     * @return Mage_Customer_Model_Customer
     * @throws Exception
     * @throws Mage_Api2_Exception
     */
    protected function _getCustomer()
    {
        if (!$this->_customer) {
            $customer = Mage::getSingleton('customer/customer')->load($this->getApiUser()->getUserId());
            if (!$customer->getId()) {
                $this->_critical('登录已过期!', Mage_Api2_Model_Resource::ERROR_NOT_LOGIN);
            }
            $this->_customer = $customer;
        }

        return $this->_customer;
    }

    /**
     * @param bool $checkQty
     * @return array|mixed
     * @throws Exception
     */
    protected function _getCartData($checkQty = false)
    {
        $data = array();
        $quote = $this->_getQuote(true);

        $giftOb = Mage::getModel('mapi/observer_gift');
        $giftOb->setContext($this);
        $giftOb->validateGift();

        //$quote->collectTotals()->save();
        $data['subtotal'] = (float)$quote->getSubtotal();
        $canUsePoints = $this->_getPointsForCheckout();
        $rate = $this->getPointsSpendRate();
        if ($canUsePoints) {
            $grandTotal = $quote->getGrandTotal() - $canUsePoints / $rate;
            if ($grandTotal <= 0) $grandTotal = 0;
        } else {
            $grandTotal = (float)$quote->getGrandTotal();
        }

        $spendHelper = $this->getSpendHelper();
        $points = $spendHelper->getCustomerPoint($this->getApiUser()->getUserId());
        /*$maxUsePoint = 0;
        if ($canUsePoints && $points) {
            if ($canUsePoints > $points) {
                $maxUsePoint = $points / $this->getPointsSpendRate();
            } else {
                $maxUsePoint = $canUsePoints / $this->getPointsSpendRate();
            }
        }*/

        $data['grand_total'] = $grandTotal/* - $maxUsePoint*/
        ;
        $itemsData = $this->_getAllItemData($checkQty);
        $data['has_error'] = $this->_hasError;
        $data['items'] = $itemsData;


        $data['point_balance'] = (int)$points;
        $data['point_used'] = (int)$canUsePoints;
        $data['point_rate'] = $this->getPointsSpendRate();
        $data['point_discount'] = $canUsePoints / $rate;

        return $data['items'] ? $data : json_decode('{}');
    }

    /**
     * @param bool $checkQty
     * @return array
     */
    protected function _getAllItemData($checkQty = false)
    {
        $_imageHelper = Mage::helper('catalog/image');
        $giftHelper = Mage::helper('mapi/gift');
        $quote = $this->_getQuote();
        $items = $quote->getAllItems();
        $itemsData = array();

        foreach ($items as $item) {
            if($item->getGiftId()) continue;
            $product = $item->getProduct();
            $errors = array();
            $stockItem = $product->getStockItem();
            $stockQty = (int)$stockItem->getQty();

            if ($checkQty) {
                $errors = $this->_getProductErrors($product, $item, false);
            }
            
            if ($errors) $this->_hasError = 1;

            //$gifts = $helper->getGiftsByProduct($product);
            $gifts = $giftHelper->getGiftItems($quote, $item);

            $exchange = (int)$item->getExchange();
            
/*             $product= Mage::getModel('catalog/product')->load(product_id);
            $specialprice = $product->getFinalPrice();  */
           
            $itemsData[] = array(
                'item_id' => $item->getId() + 0,
                'product_id' => (int)$item->getProductId(),
                'name' => $item->getName(),
                'price' => (float)$item->getPrice(),
                'image' => $_imageHelper->init($item->getProduct(), 'image')->resize(250) . "",
                'qty' => (int)$item->getQty(),
                'stock_qty' => intval($stockQty),
                'subtotal' => $exchange ? 0 : (float)$item->getRowTotal(),
                'exchange' => $exchange,
                'errors' => $errors,
                'gifts'=>$gifts
            );
        }
        return $itemsData;
    }

    /**
     * 获取站点ID
     * @return Ambigous <number, mixed, NULL, multitype:>
     */
    protected function _getstoreIdadd()
    {
    	return Mage::app()->getStore()->getId(); 
    }
    /**
     * get reward points spending block helper
     *
     * @return Silk_Mapi_Helper_Points
     */
    public function getSpendHelper()
    {
        return Mage::helper('mapi/points');
    }

    /**
     * @return float
     */
    protected function _getPointsForCheckout()
    {
        $items = $this->_getQuote()->getAllItems();
        $totalPrice = 0;
        foreach ($items as $item) {
            $prod = $item->getProduct();
            $prod->load($item->getProductId());
            if ($prod->getUsePoint() && $item->getExchange()) {
                $totalPrice += ($prod->getFinalPrice() * $item->getQty());
            }
        }
        return ceil($totalPrice * $this->getPointsSpendRate());
    }

    /**
     * @return array
     */
    protected function _getQuoteItemsCount()
    {
        return array(
            'itemsCount' => (int)$this->_getQuote(true)->getItemsCollection()->count()
        );
    }

    /**
     * @param Mage_Catalog_Model_Product $product
     * @param $itemInfo
     * @param bool $inCart
     * @return array
     */
    protected function _getProductErrors(Mage_Catalog_Model_Product $product, $itemInfo, $inCart = true)
    {
        if ($itemInfo instanceof Mage_Sales_Model_Quote_Item) {
            $qty = $itemInfo->getQty();
            $item = $itemInfo;
        } else {
            $qty = (int)$itemInfo;
            $item = $this->_getQuote()->getItemByProduct($product);
        }
        $stockItem = $product->getStockItem();
        $minimumQty = (int)$stockItem->getMinSaleQty();
        $maxQty = (int)$stockItem->getMaxSaleQty();
        $name = $product->getName();
        $stockQty = (int)$stockItem->getQty();
        $errors = array();

        if (!$stockItem->getIsInStock() || !$product->isInStock()) {
            $errors[] = array(
                'code' => Mage_Api2_Model_Resource::ERROR_CART_OUT_STOCK,
                'message' => $name . ' 已经下架！',
                'correct_qty' => 0
            );
        }

        $itemQty = 0;
        if ($item && $item->getId() && $inCart)
            $itemQty = $item->getQty();

        if (($qty + $itemQty) > $stockQty) {
            $errors[] = array(
                'code' => Mage_Api2_Model_Resource::ERROR_CART_OUT_OF_STOCK,
                'message' => $name . ' 库存不足',
                'correct_qty' => $stockQty
            );
        }

        if ($minimumQty && $minimumQty > 0 && ($qty + $itemQty) < $minimumQty) {
            $errors[] = array(
                'code' => Mage_Api2_Model_Resource::ERROR_CART_MIN_SALE_QTY,
                'message' => $name . ' 最小购买数量为：' . $minimumQty,
                'correct_qty' => $minimumQty
            );
        }

        if ($maxQty && $maxQty > 0 && ($qty + $itemQty) > $maxQty) {
            $errors[] = array(
                'code' => Mage_Api2_Model_Resource::ERROR_CART_MAX_SALE_QTY,
                'message' => $name . ' 最大购买数量为：' . $maxQty,
                'correct_qty' => $maxQty
            );
        }

        $session = $this->_getCheckoutSession();
        $exchange = $session->getExchange();
        if (!$exchange && $item) {
            $exchange = $item->getExchange();
        }

        if ($exchange) {
            $productId = $product->getId();

            $activityId = $session->getActivityId();
            if (!$activityId) {
                $activityId = $item->getActivityId();
            }

            $spendHelper = $this->getSpendHelper();
            $points = $spendHelper->getCustomerPoint($this->getApiUser()->getUserId());
            $canUsePoints = $this->_getPointsForCheckout();
            if ($canUsePoints > $points) {
                $errors[] = array(
                    'code' => Mage_Api2_Model_Resource::ERROR_UNKNOWN_ERROR,
                    'message' => "积分不足！",
                    'correct_qty' => 0
                );
            }

            /** @var Silk_Pms_Model_Mysql4_Exchangeproduct_Collection $collection */
            $collection = Mage::getResourceModel('pms/exchangeproduct_collection');
            $collection->addFieldToFilter('activity_id', $activityId)
                ->addFieldToFilter('product_id', $productId);
            $exchangeProduct = $collection->getFirstItem();
            if ($exchangeProduct && $exchangeProduct->getId()) {
                if (($exchangeProduct->getQty() - $exchangeProduct->getExchangedQty()) < $qty) {
                    $errors[] = array(
                        'code' => Mage_Api2_Model_Resource::ERROR_UNKNOWN_ERROR,
                        'message' => "超过商品兑换数量！",
                        'correct_qty' => (int)$exchangeProduct->getQty()
                    );
                } elseif ($inCart && $this->_getQuote()->hasProductId($productId) && $item) {
                    if ($item->getExchange() && ($item->getQty() + $qty > ($exchangeProduct->getQty() - $exchangeProduct->getExchangedQty()))) {
                        $errors[] = array(
                            'code' => Mage_Api2_Model_Resource::ERROR_UNKNOWN_ERROR,
                            'message' => "超过商品兑换数量！",
                            'correct_qty' => (int)$exchangeProduct->getQty()
                        );
                    }
                }
            } else {
                $errors[] = array(
                    'code' => Mage_Api2_Model_Resource::ERROR_UNKNOWN_ERROR,
                    'message' => "当前商品已兑完！",
                    'correct_qty' => 0
                );
            }
        }
        
        return $errors;
    }

    /**
     * @return mixed
     * @throws Exception
     */
    protected function getPointsRule()
    {
        $customer = $this->_getCustomer();
        Mage::getSingleton('customer/session')
            ->setCustomerId($this->getApiUser()->getUserId())
            ->setCustomerGroupId($customer->getGroupId());
        $rule = Mage::helper('rewardpoints/calculation_spending')->getSpendingRateAsRule();
        return $rule;
    }

    /**
     * @return float
     */
    protected function getPointsSpendRate()
    {
        $rule = $this->getPointsRule();
        if(!$rule) return 1;
        $rate = $rule->getPointsSpended() / $rule->getBaseRate();
        return $rate;
    }

    /**
     * @return Mage_Sales_Model_Quote
     * @throws Exception
     * @throws Mage_Api2_Exception
     */
    protected function validateQuote()
    {
        $quote = $this->_getQuote();
        if (!$quote->hasItems()) {
            $this->_critical('购物车为空！', Mage_Api2_Model_Resource::ERROR_CHECKOUT_CART_EMPTY);
        }

        $customer = $this->_getCustomer();
        $addresses = $customer->getAddressesCollection();
        if (count($addresses)) {
            $this->address = $addresses->getFirstItem();
        } else {
            $this->_critical('请先设置收货地址！', Mage_Api2_Model_Resource::ERROR_CHECKOUT_NO_ADDRESS);
        }

        $spendHelper = $this->getSpendHelper();
        $points = $spendHelper->getCustomerPoint($this->getApiUser()->getUserId());
        $pointsForCheckout = $this->_getPointsForCheckout();
        if ($pointsForCheckout > $points) {
            $this->_critical("你的积分不足！", Mage_Api2_Model_Resource::ERROR_CHECKOUT_NO_POINTS);
        }

        $items = $quote->getAllItems();
        foreach ($items as $item) {
            $product = $item->getProduct();
            $errors = $this->_getProductErrors($product, $item, false);
            if ($errors) {
                $this->_critical($errors[0]['message'], $errors[0]['code']);
            }
        }

        return $quote;
    }

    /**
     * @return Mage_Customer_Model_Entity_Address
     * @throws Exception
     * @throws Mage_Api2_Exception
     */
    protected function getCustomerDefaultAddress()
    {
        if (!$this->address) {
            $customer = $this->_getCustomer();
            $addresses = $customer->getAddressesCollection();
            if (count($addresses)) {
                $this->address = $addresses->getFirstItem();
            } else {
                $this->_critical('请先设置收货地址！', Mage_Api2_Model_Resource::ERROR_CHECKOUT_NO_ADDRESS);
            }
        }

        return $this->address;
    }

    public function getQuote($reload = false)
    {
        return $this->_getQuote($reload);
    }
}